package cn.easyutil.project.web.handler;


import cn.easyutil.project.web.advice.RawRequestAdvice;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import cn.easyutil.project.base.context.Context;
import cn.easyutil.util.javaUtil.LoggerUtil;
import cn.easyutil.project.web.util.RequestPool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Type;

/**
 * 请求为json格式的body体的时候进行解析(form表单形式的不走此方法)
 * 此处可集成加解密
 *
 * @author spc
 */
@Component
public class RawRequestAuthorition extends MappingJackson2HttpMessageConverter {

    @Autowired(required = false)
    private RawRequestAdvice jsonRequestAdvice;

    public RawRequestAuthorition(ObjectMapper objectMapper) {
        super(objectMapper);
    }

    /**
     * type:请求controller中的参数类型
     * contextClass:请求的controller类
     * inputMessage:请求的body体
     */
    @Override
    public Object read(Type type, Class<?> contextClass, HttpInputMessage inputMessage)
            throws IOException, HttpMessageNotReadableException {

        HttpServletRequest request = RequestPool.get();
        String requestUri = request.getRequestURI();
        // 请求参数
        Object result = null;
        //读取用户的请求数据
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int i;
        while ((i = inputMessage.getBody().read()) != -1) {
            baos.write(i);
        }
        //读取到原始请求数据
        String text = baos.toString();
        if(jsonRequestAdvice == null){
            jsonRequestAdvice = new DefaultRawRequestAdvice();
        }
        //进行参数处理和相关验证拦截
        text = jsonRequestAdvice.process(text,request,contextClass);
        LoggerUtil.info(contextClass,"接口【"+requestUri+"】的请求参数为:"+text);
        JavaType javaType = getJavaType(type, contextClass);
        //包装接口对应的实体对象
        Object obj = this.objectMapper.readerFor(javaType).readValue(text);
        //向返回拦截器传递当前接口路径
        String callNoStr = request.getRequestURI().substring(requestUri.lastIndexOf("/") + 1);
        RequestPool.setCacheAttribute(Context.threadLocal_request_url, callNoStr);
        return obj;
    }

    @Override
    protected void writeInternal(Object object, Type type, HttpOutputMessage outputMessage)
            throws IOException, HttpMessageNotWritableException {

        super.writeInternal(object, type, outputMessage);
    }
}
